package com.china08.yxyapi.util;

import java.sql.Time;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.apache.commons.lang3.StringUtils;

public class DateUtils {

    private static final long ONE_SECOND = 1000L;
    private static final long ONE_MINUTE = 60000L;
    private static final long ONE_HOUR = 3600000L;
    private static final long ONE_DAY = 86400000L;
    private static final long ONE_WEEK = 604800000L;
    private static final long ONE_MONTH = 2592000000L;
    private static final long ONE_YEAR = 31536000000L;

    private static final String ONE_SECOND_AGO = "秒前";
    private static final String ONE_MINUTE_AGO = "分钟前";
    private static final String ONE_HOUR_AGO = "小时前";
    private static final String ONE_DAY_AGO = "天前";
    private static final String ONE_WEEK_AGO = "周前";
    private static final String ONE_MONTH_AGO = "月前";
    private static final String ONE_YEAR_AGO = "年前";

    public static String format(Date date) {
        // ##
        // 当前日期
        Calendar currcalendar = Calendar.getInstance();
        currcalendar.setTime(new Date());

        // ##
        // 处理日期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        if (currcalendar.get(Calendar.YEAR) == calendar.get(Calendar.YEAR)) {
            long delta = new Date().getTime() - date.getTime();
            if (delta < 1L * ONE_MINUTE) {
                long seconds = toSeconds(delta);
                return (seconds <= 0 ? 1 : seconds) + ONE_SECOND_AGO;
            }
            if (delta < 45L * ONE_MINUTE) {
                long minutes = toMinutes(delta);
                return (minutes <= 0 ? 1 : minutes) + ONE_MINUTE_AGO;
            }
            if (delta < 24L * ONE_HOUR) {
                long hours = toHours(delta);
                return (hours <= 0 ? 1 : hours) + ONE_HOUR_AGO;
            }
            if (delta < 48L * ONE_HOUR) { return "昨天"; }
            if (delta < 30L * ONE_DAY) {
                long days = toDays(delta);
                return (days <= 0 ? 1 : days) + ONE_DAY_AGO;
            }
            if (delta < 12L * 4L * ONE_WEEK) {
                SimpleDateFormat format = new SimpleDateFormat("MM-dd");
                return format.format(date);
            } else {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                return format.format(date);
            }
        } else {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            return format.format(date);
        }

    }

    private static long toSeconds(long date) {
        return date / 1000L;
    }

    private static long toMinutes(long date) {
        return toSeconds(date) / 60L;
    }

    private static long toHours(long date) {
        return toMinutes(date) / 60L;
    }

    private static long toDays(long date) {
        return toHours(date) / 24L;
    }

    public static String formatDate3(Date date) {
        DateFormat df = new SimpleDateFormat("MM月dd日HH:mm");
        return df.format(date);
    }

    public static Integer formatDate6(Date date) {
        DateFormat df = new SimpleDateFormat("yyyyMM");
        return Integer.parseInt(df.format(date));
    }

    public static String formatDate5(Date date) {
        DateFormat df = new SimpleDateFormat("MM月dd日");
        return df.format(date);
    }

    public static String formatDate11(Date date) {
        DateFormat df = new SimpleDateFormat("HH:mm");
        return df.format(date);
    }

    /**
     * @param date
     * @return
     */
    public static String formatDate7(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyMMdd");
        return df.format(date);
    }

    public static String formatDate8(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(date);
    }

    public static String formatDate10(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        return df.format(date);
    }

    public static Integer formatDate4(Date date) {
        DateFormat df = new SimpleDateFormat("yyyyMMdd");
        return Integer.parseInt(df.format(date));
    }

    public static Date formatStrDate(String date) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.parse(date);
    }

    /**
     * yyyyMM
     * 
     * @param monthAndYear
     * @return
     * @throws ParseException
     */
    public static Date formatIntDate5(Integer monthAndYear) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMM");
        return df.parse(monthAndYear + "");
    }

    public static Date formatStrDate4(Integer date) throws ParseException {
        return formatStrDate3(date + "");
    }

    public static Date formatStrDate3(String date) throws ParseException {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        return df.parse(date);
    }

    public static String formatDate2(Date date) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        return df.format(date);
    }

    public static Date getDate(Integer day, Time time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Integer.parseInt(StringUtils.substring("" + day, 0, 4)), Integer.parseInt(StringUtils.substring("" + day, 4, 6)) - 1, Integer.parseInt(StringUtils.substring("" + day, 6, 8)));
        return calendar.getTime();
    }

    public static Time getTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, date.getHours());
        calendar.set(Calendar.MINUTE, date.getMinutes());
        calendar.set(Calendar.SECOND, date.getSeconds());
        calendar.set(Calendar.YEAR, 1970);
        calendar.set(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        return new Time(calendar.getTimeInMillis());
    }

    public static boolean greaterCompareDate(Time date1, Time date2) {
        return date1.compareTo(date2) > 0;
    }

    public static boolean greaterEqualCompareDate(Time date1, Time date2) {
        return date1.compareTo(date2) >= 0;
    }

    public static boolean lessEqualCompareDate(Time date1, Time date2) {
        return date1.compareTo(date2) <= 0;
    }

    /**
     * 获取前一天
     * 
     * @param date
     * @return
     */
    public static Date getBeforeDay(Date date) {
        return org.apache.commons.lang3.time.DateUtils.addDays(date, -1);
    }

    /** 年份 */
    public static int year(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /** 月份 */
    public static int month(Date date) {
        // 注：月份是从0开始的，所以11表示12月，需要加一
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /** 日期 */
    public static int date(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }

    /** 周几 */
    public static String week(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return Week(calendar.get(Calendar.DAY_OF_WEEK));
    }

    /** 当前时间减几个月 */
    public static Date subtractMonth(Date date, int i) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -i);
        return calendar.getTime();
    }

    /** 当前时间减几天 */
    public static Date subtractDay(Date date, int i) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -i);
        return calendar.getTime();
    }

    /** 当前时间减几周 */
    public static Date subtractWeek(Date date, int i) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -(7 * i));
        return calendar.getTime();
    }

    /** 某个月份当月第一天 */
    public static Date getMothOfFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        return calendar.getTime();
    }

    /** 某个月份当月最后一天 */
    public static Date getMothOfLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    /** 获取某一天0点时间 */
    public static Date getFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /** 获取某一天24点时间 */
    public static Date getTimesnight(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /** 得到本周周一 */
    public static Date getMondayOfThisWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) day_of_week = 7;
        calendar.add(Calendar.DATE, -day_of_week + 1);
        return calendar.getTime();
    }

    /** 得到本周周日 */
    public static Date getSundayOfThisWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) day_of_week = 7;
        calendar.add(Calendar.DATE, -day_of_week + 7);
        return calendar.getTime();
    }

    /** 得到本周周一 1 */
    public static Date getMondayOfThisWeek1(Date date) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek - 1);
        Date firstDayOfWeek = cal.getTime();
        return firstDayOfWeek;
    }

    /** 得到本周周日 1 */
    public static Date getSundayOfThisWeek1(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek + 5);
        Date firstDayOfWeek = cal.getTime();
        return firstDayOfWeek;
    }

    /** 得到本周記日期 **/
    public static Date getThisWeek(Date date, int i) {
        if (i < 1 && i > 7) {
            i = 1;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int day_of_week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0) day_of_week = 7;
        calendar.add(Calendar.DATE, -day_of_week + i);
        return calendar.getTime();
    }

    /** 当前第几周(自然周) */
    public static int getWeekOfYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /** 取得当前日期所在周的第一天 (本周一) */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // Monday
        return c.getTime();
    }

    /** 取得当前日期所在周的最后一天 (本周日) */
    public static Date getLastDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6); // Sunday
        return c.getTime();
    }

    /** 取得当前日期所在周的第一天 (上周日) */
    public static Date getFirstDayOfWeek1(Integer weekNum) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.WEEK_OF_YEAR, weekNum);// weekNum为周数
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        cal.add(Calendar.DATE, cal.getActualMinimum(Calendar.DAY_OF_WEEK) - dayOfWeek);
        cal.add(Calendar.DATE, 0);
        Date firstDayOfWeek = DateUtils.getFirstDay(cal.getTime());
        return firstDayOfWeek;
    }

    /** 取得当前日期所在周的最后一天(本周六) */
    public static Date getLastDayOfWeek1(Integer weekNum) {

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.WEEK_OF_YEAR, weekNum);// weekNum为周数
        int dayOfWeek1 = cal.get(Calendar.DAY_OF_WEEK);
        Calendar cal1 = (Calendar) cal.clone();
        cal1.add(Calendar.DATE, cal1.getActualMaximum(Calendar.DAY_OF_WEEK) - dayOfWeek1);
        cal1.add(Calendar.DATE, 0);
        Date lastDayOfWeek = DateUtils.getFirstDay(cal1.getTime());
        return lastDayOfWeek;
    }

    /** 日期转化 */
    public static String Week(int i) {
        switch (i) {
        case 1: {
            return "七";
        }
        case 2: {
            return "一";
        }
        case 3: {
            return "二";
        }
        case 4: {
            return "三";
        }
        case 5: {
            return "四";
        }
        case 6: {
            return "五";
        }
        case 7: {
            return "六";
        }
        default:
            return "七";
        }
    }

    /** 周几 */
    public static int getWeek2(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    /** 周几 */
    public static String getWeek1(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return Week1(calendar.get(Calendar.DAY_OF_WEEK));
    }

    /** 日期转化 */
    public static String Week1(int i) {
        switch (i) {
        case 1: {
            return "星期日";
        }
        case 2: {
            return "星期一";
        }
        case 3: {
            return "星期二";
        }
        case 4: {
            return "星期三";
        }
        case 5: {
            return "星期四";
        }
        case 6: {
            return "星期五";
        }
        case 7: {
            return "星期六";
        }
        default:
            return "星期日";
        }
    }

    public static Date minusOneDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year(date), month(date) - 1, date(date) - 1);
        return calendar.getTime();
    }

    /**
     * 比较两个时间大小： 前者大返回 1，前者小返回 -1，相等返回0
     * 
     * @param date1
     * @param date2
     */
    public static int diffmin(Date date1, Date date2) {
        if (date1.getTime() - date2.getTime() > 0) {
            return 1;
        } else if (date1.getTime() - date2.getTime() < 0) {
            return -1;
        } else {
            return 0;
        }
    }

    /**
     * 比较两个时间之差
     * 
     * @param date1
     * @param date2
     */
    public static long difference(Date date1, Date date2) {
        return (long) (Math.abs((date1.getTime() - date2.getTime())) / (1000 * 60 * 60 * 24) + 0.5);
    }

    /**
     * 比较两个时间之差
     * 
     * @param date1
     * @param date2
     */
    public static long difference2(Date date1, Date date2) {
        return (long) (Math.abs((date1.getTime() - date2.getTime())) / (1000 * 60) + 0.5);
    }

    /**
     * <span>根据时间间隔的毫秒数转化成指定时间格式的字符串间隔日期时间<span>
     * <p>
     * eg: xx 年 xx 月 xx 周 xx 日 xx 时 xx分 xx 秒
     * </p>
     * <p>
     * 例如: 间隔 60005 毫秒数 相隔时间为 1分5秒 的字符串相隔时间
     * </p>
     * 
     * @param duration
     *            相隔 毫秒数
     * @return 相隔时间字符串
     */
    public static String getDurationDateByDurationCount(Long duration) {
        if (duration == null) {//
            return "";
        }
        if (duration == 0) {//
            return "0秒";
        }
        if (duration >= ONE_YEAR) {
            int year = (int) (duration / ONE_YEAR);
            int month = (int) (duration % ONE_YEAR / ONE_MONTH);
            return year + "年" + month + "月";
        } else if (duration >= ONE_MONTH) {
            int month = (int) (duration / ONE_MONTH);
            int week = (int) (duration % ONE_MONTH / ONE_WEEK);
            return month + "月" + week + "周";
        } else if (duration >= ONE_WEEK) {
            int week = (int) (duration / ONE_WEEK);
            int day = (int) (duration % ONE_WEEK / ONE_DAY);
            return week + "周" + day + "日";
        } else if (duration >= ONE_DAY) {
            int day = (int) (duration / ONE_DAY);
            int hour = (int) (duration % ONE_DAY / ONE_HOUR);
            return day + "日" + hour + "小时";
        } else if (duration >= ONE_HOUR) {
            int hour = (int) (duration / ONE_HOUR);
            int minute = (int) (duration % ONE_HOUR / ONE_MINUTE);
            return hour + "小时" + minute + "分";
        } else if (duration >= ONE_MINUTE) {
            int minute = (int) (duration / ONE_MINUTE);
            int second = (int) (duration % ONE_MINUTE / ONE_SECOND);
            return minute + "分" + second + "秒";
        } else {
            int second = (int) (duration / ONE_SECOND);
            if (second == 0) {
                second = 0;
            }
            return second + "秒";
        }
    }
}
